/**  
 * File Name:UserFilter.java  
 * Package Name:com.suneee.dmt.util  
 * Description: (That's the purpose of the file)
 * Date:2015年5月14日下午1:46:11  
 * Copyright (c) 2015, forint.lee@qq.com All Rights Reserved.  
 *  
 */

package com.suneee.base.filter;

import java.io.IOException;
import java.io.PrintWriter;
import java.util.Arrays;
import java.util.Date;
import java.util.List;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.suneee.base.context.OnlineUser;
import com.suneee.base.context.Session;
import com.suneee.base.entity.DeviceType;
import com.suneee.base.util.UserThreadLocal;
import com.suneee.cloud.admin.resources.AdminError;
import com.suneee.component.cache.CacheUtils;
import com.suneee.component.cache.thread.ThreadLocalCache;
import com.suneee.context.util.SpringContextHelper;
import com.suneee.core.error.Assert;
import com.suneee.core.error.ErrorUtils;
import com.suneee.core.type.json.JsonUtils;
import com.suneee.core.util.DateUtils;
import com.suneee.core.util.StringUtils;
import com.suneee.sso.admin.service.IAdminUserLoginService;
import com.suneee.web.util.CookieUtils;

/**
 * ClassName:UserFilter <br/>
 * Description:That's the purpose of the class Date: 2015年5月14日 下午1:46:11 <br/>
 * 
 * @author SUNEE-CC
 * @version V1.0
 * @see
 */
public class UserFilter implements Filter {
	private static final Logger logger = LoggerFactory.getLogger(UserFilter.class);
	private static String WELCOME_PAGE = null;//首页
	private static List<String> INGORE_DIRETORY = null;//页面
	private static List<String> INGORE_INTERFACE = null;//接口
	private static List<String> INGORE_PAGE = null;//公共
	public static final String REQUEST = "request";
	public static final String RESPONSE = "response";
	public static final String COOKIE_SESSION = "sessionId";
	
	@Override
	public void destroy() {
		UserThreadLocal.clear();
	}

	@Override
	public void init(FilterConfig filterConfig) throws ServletException {
		WELCOME_PAGE = filterConfig.getInitParameter("WELCOME_PAGE");

		Assert.notEmpty(WELCOME_PAGE, "WELCOME_PAGE");
		String arrs = filterConfig.getInitParameter("INGORE_PAGE");
		Assert.notEmpty(arrs, "INGORE_PAGE");
		INGORE_PAGE = Arrays.asList(arrs.split(","));

		String arrss = filterConfig.getInitParameter("INGORE_DIRETORY");
		Assert.notEmpty(arrs, "INGORE_DIRETORY");
		INGORE_DIRETORY = Arrays.asList(arrss.split(","));

		String interfacearrs = filterConfig.getInitParameter("INGORE_INTERFACE");
		Assert.notEmpty(arrs, "INGORE_INTERFACE");
		INGORE_INTERFACE = Arrays.asList(interfacearrs.split(","));
	}
	
	@Override
	public void doFilter(ServletRequest request, ServletResponse response, FilterChain fchain) throws IOException, ServletException {
		HttpServletRequest req = (HttpServletRequest) request;
		HttpServletResponse resp = (HttpServletResponse) response;
		//req.setCharacterEncoding("UTF-8");
		//resp.setCharacterEncoding("UTF-8");
		//Administrator user=(Administrator) session.getAttribute("LOGINUSER");
		
		
		ThreadLocalCache.setObject(REQUEST, req);
		ThreadLocalCache.setObject(RESPONSE, resp);
		
		String pathInfo=req.getServletPath();
		
		
		Session session = this.initContext(req, resp);
		
		if (StringUtils.isEmpty(pathInfo) || "/".equals(pathInfo)) {
			req.getRequestDispatcher(WELCOME_PAGE).forward(request, response);
			return;
		}//else if(){
			
		//}
	    else{
			boolean flag = false;
			for (String string : INGORE_PAGE) {
				if (pathInfo.endsWith(string)) {
					resp.setHeader("Content-type", "text/html;charset=UTF-8");
					flag = true;
					break;
				}
			}
			for (String string : INGORE_INTERFACE) {
				if (pathInfo.startsWith(string)) {
					flag = true;
					break;
				}
			}
			for (String string : INGORE_DIRETORY) {
				if (pathInfo.startsWith(string)) {
					flag = true;
					break;
				}
			}

			if (!flag) {
				if (this.checkTimeout(session)) {
					this.writeTimeout(req, resp);
					return;
				}
			}
		}
		fchain.doFilter(request, response);
	}
	
	private Session initContext(HttpServletRequest request,HttpServletResponse response) {

		String sessionId = CookieUtils.getCookieValue(request, COOKIE_SESSION);
		Session session = null;

		if (StringUtils.isEmpty(sessionId) || !CacheUtils.get(Session.class).exists(sessionId)) {
			sessionId = StringUtils.getUUID();
			session = new Session(sessionId, request.getRemoteAddr(), DeviceType.DESKTOP, DateUtils.getCurrentTimestamp());

			CookieUtils.setCookie((HttpServletRequest) request, (HttpServletResponse) response, COOKIE_SESSION, sessionId);
			CacheUtils.get(Session.class).put(sessionId, session);
		} else {
			session = CacheUtils.get(Session.class).get(sessionId);
		}
		UserThreadLocal.setSession(session);
		return session;
	}
	
	private boolean checkTimeout(Session session) {
		OnlineUser onlineUser = session.getOnlineUser();
		
		if (onlineUser == null) {
			return true;
		}
		Long time = new Date().getTime();
		long misDate = (time - onlineUser.getLastVisitedTime().getTime()) / 1000 / 60;
		if (misDate >= 30) {
			try {
				SpringContextHelper.getBean(IAdminUserLoginService.class).loginOut(onlineUser.getSessionId());
			} catch (Exception e) {
				logger.error("AdministratorService logout " + e.getMessage(), e);
			}
			return true;
		}else {
			onlineUser.setLastVisitedTime(DateUtils.getTimestamp(time));
			CacheUtils.get(Session.class).update(session.getSessionId(),session);
		}
		return false;
	}
	
	private void writeTimeout(HttpServletRequest request,
			HttpServletResponse response) throws IOException, ServletException {
		request.setCharacterEncoding("UTF-8");
		response.setCharacterEncoding("UTF-8");
		response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
		response.setContentType("application/json;charset=utf-8");
		PrintWriter writer = response.getWriter();
		//登录过期
		String json = JsonUtils.mapper().writeValueAsString(ErrorUtils.wrap(AdminError.TIMEOUT_SESSION));
		String jsonp = request.getParameter("_jsonp");
		if (jsonp == null) {
			writer.print(json);
		} else {
			writer.print(jsonp + "(" + json + ");");
		}
	}

}
